package cn.opencodes.db;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * 数据库配置文件读取方法
 * @author HJ
 */
public class DbConfig {
	/**
     * 数据库驱动
     */
    private String driver;
    /**
     * 数据库连接地址
     */
    private String url;
    /**
     * 用户名
     */
    private String userName;
    /**
     * 密码
     */
    private String password;
     
    public DbConfig() { }
    
    public DbConfig(String driver, String url, String userName, String password) {
    	this.driver = driver;
    	this.url = url;
    	this.userName = userName;
    	this.password = password;
    }

	public String getDriver() {
		return driver;
	}

	public String getUrl() {
		return url;
	}

	public String getUserName() {
		return userName;
	}

	public String getPassword() {
		return password;
	}

	public void setDriver(String driver) {
		this.driver = driver;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public void setPassword(String password) {
		this.password = password;
	}
    
	private Connection conn;
	private PreparedStatement preparedStatement;
	private CallableStatement callableStatement;
	
	/**
     * 建立数据库连接
     * 
     * @return
     * @throws SQLException
     */
	public Connection getConnection() {
        if (conn != null) {
			return conn;
		}
        try {
        	Class.forName(driver);
        	conn = DriverManager.getConnection(url, userName, password);
        } catch (Exception e) {
            throw new RuntimeException("创建 Connection 发生异常", e);
        }
        return conn;
    }
	
	 /**
     * 获取PreparedStatement
     * @param sql
     */
	public PreparedStatement getPreparedStatement(String sql) {
		if (preparedStatement != null) {
			return preparedStatement;
		}
        try {
        	preparedStatement = getConnection().prepareStatement(sql);
        } catch (Exception e) {
        	throw new RuntimeException("创建 PreparedStatement 发生异常", e);
        }
        return preparedStatement;
    }
	
	 /**
     * 获取CallableStatement
     * @param procedureSql
     */
	public CallableStatement getCallableStatement(String procedureSql){
    	if (callableStatement != null) {
			return callableStatement;
		}
        try {
        	callableStatement = getConnection().prepareCall(procedureSql);
        } catch (Exception e) {
        	throw new RuntimeException("创建 callableStatement 发生异常", e);
        }
        return callableStatement;
    }
 
    /**
     * 释放连接
     * @param conn
     */
	private void freeConnection(Connection conn) {
        try {
            conn.close();
        } catch (SQLException e) {
        	throw new RuntimeException("关闭 Connection 发生异常", e);
        }
    }
 
    /**
     * 释放statement
     * @param statement
     */
	private void freeStatement(Statement statement) {
        try {
            statement.close();
        } catch (SQLException e) {
        	throw new RuntimeException("关闭 Statement 发生异常", e);
        }
    }
    
    /**
     * 释放ResultSet
     * @param rs
     */
	private void freeResultSet(ResultSet rs) {
        try {
            rs.close();
        } catch (SQLException e) {
        	throw new RuntimeException("关闭 ResultSet 发生异常", e);
        }
    }
	
	/**
    * 释放资源---preparedStatement
    * @param rs 结果集
    */
   public void freePrep(ResultSet rs) {
       free(conn, preparedStatement, rs);
   }
   
   /**
    * 释放资源---callableStatement
    * @param rs 结果集
    */
   public void freepCall(ResultSet rs) {
   		free(conn, callableStatement, rs);
   }
 
    /**
     * 释放资源
     * 
     * @param conn
     * @param statement
     * @param rs
     */
	public void free(Connection conn, Statement statement, ResultSet rs) {
        if (rs != null) {
            freeResultSet(rs);
        }
        if (statement != null) {
            freeStatement(statement);
        }
        if (conn != null) {
            freeConnection(conn);
        }
        rs = null;
        this.preparedStatement = null;
        this.callableStatement = null;
	    this.conn = null;
    }
 
}